package com.ruoyi.framework.config.properties

import com.ruoyi.framework.aspectj.lang.annotation.Anonymous
import org.apache.commons.lang3.RegExUtils
import org.springframework.beans.BeansException
import org.springframework.beans.factory.InitializingBean
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware
import org.springframework.context.annotation.Configuration
import org.springframework.core.annotation.AnnotationUtils
import org.springframework.web.servlet.mvc.method.RequestMappingInfo
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
import java.util.*
import java.util.function.Consumer
import java.util.regex.Pattern

/**
 * 设置Anonymous注解允许匿名访问的url
 *
 * @author ruoyi
 */
@Configuration
open class PermitAllUrlProperties : InitializingBean, ApplicationContextAware {
    private var applicationContext: ApplicationContext? = null
    var urls: MutableList<String> = ArrayList()
    private val ASTERISK = "*"

    override fun afterPropertiesSet() {
        val mapping = applicationContext!!.getBean(RequestMappingHandlerMapping::class.java)
        val map = mapping.handlerMethods
        /*map.keys.forEach(Consumer { info: RequestMappingInfo ->
            val handlerMethod = map[info]

            // 获取方法上边的注解 替代path variable 为 *
            val method = AnnotationUtils.findAnnotation(handlerMethod!!.method, Anonymous::class.java)

            method.apply {
                info.patternsCondition?.patterns?.forEach { url ->
                    urls.add(
                            RegExUtils.replaceAll(
                                    url,
                                    PATTERN,
                                    ASTERISK
                            )
                    )
                }
            }
            // 获取类上边的注解, 替代path variable 为 *
            val controller = AnnotationUtils.findAnnotation(handlerMethod.beanType, Anonymous::class.java)
            controller.apply {
                info.patternsCondition?.patterns?.forEach { url ->
                    urls.add(
                            RegExUtils.replaceAll(
                                    url,
                                    PATTERN,
                                    ASTERISK
                            )
                    )
                }
            }
        })*/
        map.keys.forEach(Consumer { info: RequestMappingInfo ->
            val handlerMethod = map[info]

            // 获取方法上边的注解 替代path variable 为 *
            val method = AnnotationUtils.findAnnotation(handlerMethod!!.method, Anonymous::class.java)
            Optional.ofNullable(method).ifPresent {
                assert(info.patternsCondition != null)
                info.patternsCondition?.patterns
                    ?.forEach(Consumer { url: String? -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK)) })
            }

            // 获取类上边的注解, 替代path variable 为 *
            val controller = AnnotationUtils.findAnnotation(handlerMethod.beanType, Anonymous::class.java)
            Optional.ofNullable(controller).ifPresent {
                assert(info.patternsCondition != null)
                info.patternsCondition?.patterns
                    ?.forEach(Consumer { url: String? -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK)) })
            }
        })
    }

    @Throws(BeansException::class)
    override fun setApplicationContext(context: ApplicationContext) {
        applicationContext = context
    }

//    @JvmName("getUrls")
//    fun getUrls(): List<String> {
//        return urls
//    }

    companion object {
        private val PATTERN = Pattern.compile("\\{(.*?)}")
    }
}
